#include "StdAfx.h"
#include "SvrNetRealStreamMan.h"
#include "TGSvrNetMan.h"


SvrNetRealStreamMan::SvrNetRealStreamMan(void)
{
	m_pSvrNetMan = NULL;

	m_nUseCount = 0;
	for(int i=0;i<TG_SVRNET_MAXCHANNEL;i++)
	{
		m_arCamera[i] = NULL;
	}

	m_hCommandEvent = NULL;
}

SvrNetRealStreamMan::~SvrNetRealStreamMan(void)
{
	UnInitialize();
}

int SvrNetRealStreamMan::SetSvrNetMan(TGSvrNetMan *pSvrNet)
{
	m_pSvrNetMan = pSvrNet;

	InitializeNetCmd();
	
	return 0;
}

int SvrNetRealStreamMan::UnInitialize()
{
	UnInitializeNetCmd();
	
	for(int i=0;i<TG_SVRNET_MAXCHANNEL;i++)
	{
		TG_AUTO_LOCK xLock2(&m_xCameraSect[i]);
		MySafeDelete(m_arCamera[i]);
		xLock2.CancelLock();
	}

	return 0;
}

//#define dkq_test_20100714

int SvrNetRealStreamMan::OpenCamera(NET_PACKET_HEAD *pRetMsgHead,TG_CONNECT_INFO *pConnectInfo,SOCKET hSocket,TG_UDP_ADDR *pAddr)
{
	if( NULL == pRetMsgHead   ||
		NULL == pConnectInfo  ||
		pConnectInfo->xDevInfo.nCameraNum > TG_SVRNET_MAXCHANNEL )
	{
		return TG_ERR_PARAMETER_ERROR;
	}

	int nRet = TG_ERR_FAILURE;

	try
	{
		UINT16 i=0;
		SvrNetRPCamera *pCamera = NULL;
		for(i=0;i<m_nUseCount;i++)
		{
			pCamera = m_arCamera[i];
			if( NULL != pCamera)
			{
				TG_AUTO_LOCK xLock2(&m_xCameraSect[i]);

				pCamera = m_arCamera[i];
				if( NULL != pCamera && !pCamera->CheckIsWorking() )
				{
					MySafeDelete(m_arCamera[i]);
				}

				xLock2.CancelLock();
			}
		}

		SINT16 nCameraPos = GetCameraPos( &pConnectInfo->xDevInfo );
		if( nCameraPos >= 0 )
		{
            TG_AUTO_LOCK xLock(&m_xCameraSect[nCameraPos]); 

			nRet = m_arCamera[nCameraPos]->AddItem(pRetMsgHead,pConnectInfo,hSocket,pAddr);
		}
		else
		{
			i = 0;
			pCamera = NULL;
			for(i=0;i<m_nUseCount;i++)
			{
				pCamera = m_arCamera[i];
				if( NULL == pCamera)
				{
					nCameraPos = i;
					break;
				}
			}
			if( i >= TG_SVRNET_MAXCHANNEL )
			{
				return TG_ERR_MAX_NUM;
			}
			if( i >= m_nUseCount )
			{
				m_nUseCount += 1;
				nCameraPos = i;
			}

			TG_AUTO_LOCK xLock2(&m_xCameraSect[nCameraPos]);

			pCamera = new SvrNetRPCamera(m_pSvrNetMan);
			if( NULL == pCamera || !pCamera->Initialize() )
			{
				nRet = TG_ERR_INITERROR;
				MySafeDelete( pCamera );
				return nRet;
			} 
			m_arCamera[nCameraPos] = pCamera;

			pCamera->SetCameraPos( nCameraPos,&pConnectInfo->xDevInfo );
			pCamera->OpenCamera(pConnectInfo);

			nRet = pCamera->AddItem(pRetMsgHead,pConnectInfo,hSocket,pAddr);
		}
	}
	catch (...)
	{
	}

	return nRet;
}

inline SINT16 SvrNetRealStreamMan::GetCameraPos( TG_DEV_INFO *pDevInfo )
{
	SINT16 nCameraPos = -1;
    for(UINT16 i=0;i<m_nUseCount;i++)
	{
        if( NULL != m_arCamera[i] )
		{
			if( 0 == memcmp(pDevInfo,&(m_arCamera[i]->m_xDevInfo),(sizeof(UINT32)+sizeof(UINT16)) ) )
			{
                nCameraPos = i;
				break;
			}
		}
	}
	return nCameraPos;
}

inline SvrNetRPCamera* SvrNetRealStreamMan::GetCameraPoint( TG_DEV_INFO *pDevInfo )
{
	SvrNetRPCamera *pCamera = NULL;
	for(UINT16 i=0;i<m_nUseCount;i++)
	{
		if( NULL != m_arCamera[i] )
		{
			if( 0 == memcmp(pDevInfo,&(m_arCamera[i]->m_xDevInfo),(sizeof(UINT32)+sizeof(UINT16)) ) )
			{
				pCamera = m_arCamera[i];
				break;
			}
		}
	}
	return pCamera;
}

int SvrNetRealStreamMan::RemoveCamera(TG_DEV_INFO *pDevInfo)
{
	SINT16 nCameraPos = GetCameraPos( pDevInfo );
	if( 0 <= nCameraPos && nCameraPos < TG_SVRNET_MAXCHANNEL )
	{
		TG_AUTO_LOCK xLock(&m_xCameraSect[nCameraPos]);
	}

	return 0;
}

int SvrNetRealStreamMan::RemoveCameraItem(TG_DEV_INFO *pDevInfo,TGHANDLE hItem)
{
	SINT16 nCameraPos = GetCameraPos( pDevInfo );
	if( 0 <= nCameraPos && nCameraPos < TG_SVRNET_MAXCHANNEL )
	{
		TG_AUTO_LOCK xLock(&m_xCameraSect[nCameraPos]);

		SvrNetRPCamera *pCamera = m_arCamera[nCameraPos];
		if( NULL != pCamera )
		{
			return pCamera->RemoveItem(hItem);
		}
	}

	return -1;
}

int SvrNetRealStreamMan::GetCameraItemCount(TG_DEV_INFO *pDevInfo,UINT32 &nCount)
{
	SINT16 nCameraPos = GetCameraPos( pDevInfo );
	if( 0 <= nCameraPos && nCameraPos < TG_SVRNET_MAXCHANNEL )
	{
		TG_AUTO_LOCK xLock(&m_xCameraSect[nCameraPos]);

		SvrNetRPCamera *pCamera = m_arCamera[nCameraPos];
		if( NULL != pCamera )
		{
			return pCamera->GetItemCount(nCount);
		}
	}

	return -1;
}


int SvrNetRealStreamMan::SetRealStreamFrame(TG_DEV_INFO *pDevInfo,void *pFrame,UINT32 lFrameSize)
{
	SINT16 nCameraPos = GetCameraPos( pDevInfo );
	if( 0 <= nCameraPos && nCameraPos < TG_SVRNET_MAXCHANNEL )
	{
		TG_AUTO_LOCK xLock(&m_xCameraSect[nCameraPos]);

		SvrNetRPCamera *pCamera = m_arCamera[nCameraPos];
		if( NULL != pCamera )
		{
			return pCamera->SetFrame(pFrame,lFrameSize);
		}
	}

	return -1;
}



void SvrNetRealStreamMan::UnInitializeNetCmd()
{
	TGThread::m_bThreadRun = false;
	if( NULL != m_hCommandEvent )
	{
		SetEvent( m_hCommandEvent );
	}
	TGThread::TGThdUnInit();

	MySafeCloseHandle( m_hCommandEvent );
}

void SvrNetRealStreamMan::InitializeNetCmd()
{
	NET_PACKET_NODE *pPacketList = &(m_xNetCommand[0]);

	UINT32 nLast = TG_SVNNET_MAXCOMMAND - 1;
	//next
	UINT32 i = 0;
	for(i=0;i<nLast;i++)
	{
		pPacketList[i].pNext      = &pPacketList[i+1];
		pPacketList[i].nPacketID  = i;
		pPacketList[i].nWriteFlag = 1;
	}
	pPacketList[nLast].pNext     = &pPacketList[0];
	pPacketList[nLast].nPacketID = nLast;
	pPacketList[nLast].nWriteFlag = 1;
	//prev
	for(i=1;i<TG_SVNNET_MAXCOMMAND;i++)
	{
		pPacketList[i].pPrev = &pPacketList[i-1];
	}
	pPacketList[0].pPrev = &pPacketList[nLast];

	m_pWriteCmdNode = pPacketList;
	m_pReadCmdNode  = NULL;


	m_hCommandEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
	if( NULL == m_hCommandEvent )
	{
		return;
	}
	ResetEvent(m_hCommandEvent);


	TGThread::TGThdInit();
}



int SvrNetRealStreamMan::SetCommand(NET_PACKET *pPacket)
{
 	m_pWriteCmdNode->xPacket.xPacketHead = pPacket->xPacketHead;
	if( pPacket->xPacketHead.nFrameSize > 0 )
	{
       memcpy( m_pWriteCmdNode->xPacket.cPacketData,pPacket->cPacketData,pPacket->xPacketHead.nFrameSize );
	}
	m_pWriteCmdNode->nWriteFlag = 0;

	if( NULL == m_pReadCmdNode )
	{
		m_pReadCmdNode = m_pWriteCmdNode;
	}

	m_pWriteCmdNode = m_pWriteCmdNode->pNext;

	SetEvent( m_hCommandEvent );

	return TG_ERR_SUCCESS;
}



int SvrNetRealStreamMan::TGThdDispatch(HANDLE hExitEvent)
{
#ifdef dkq_test_svrnet
	m_pSvrNetMan->m_xLog.WriteLog(__FILE__,__LINE__,"SvrNetRealStreamMan::TGThdDispatch start!");
#endif

	SetThreadPriority(GetCurrentThread() , THREAD_PRIORITY_ABOVE_NORMAL);

	while( TGThread::m_bThreadRun )
	{
		WaitForSingleObject( m_hCommandEvent, INFINITE );
		if( !TGThread::m_bThreadRun )
		{
			break;
		}	

		DoCommand();
	}


#ifdef dkq_test_svrnet
	m_pSvrNetMan->m_xLog.WriteLog(__FILE__,__LINE__,"SvrNetRealStreamMan::TGThdDispatch stop!");
#endif

	return 0;
}

inline void SvrNetRealStreamMan::DoCommand()
{
	if( NULL == m_pReadCmdNode )
	{
		m_pReadCmdNode = m_pWriteCmdNode->pPrev;
	}
	if( m_pReadCmdNode->nWriteFlag )
	{
		ResetEvent( m_hCommandEvent );
		return;
	}

	int nRet = TG_ERR_SUCCESS;

	NET_PACKET *pPacket = &(m_pReadCmdNode->xPacket);
	switch( pPacket->xPacketHead.nMsgType )
	{
	case MSG_TYPE_TGD_CLIENT_ALIVE:
		{
			NET_SVR_RS_CONTEXT *pContext = (NET_SVR_RS_CONTEXT*)( pPacket->cPacketData );

			UINT16 nCameraPos = pContext->nSvrRsCameraPos;

			if( 0 <= nCameraPos && nCameraPos < TG_SVRNET_MAXCHANNEL )
			{
				TG_AUTO_LOCK xLock(&m_xCameraSect[nCameraPos]);

				SvrNetRPCamera *pCamera = m_arCamera[nCameraPos];
				if( NULL != pCamera )
				{
					pCamera->KeepAlive(pContext);
				}
			}
		}
		break;
	case MSG_TYPE_TGD_RETRANS_PACKET:
	case MSG_TYPE_TGD_CHANGE_NET_STATE:
		{
			NET_SVR_RS_CONTEXT *pContext = (NET_SVR_RS_CONTEXT*)( pPacket->cPacketData );
			NET_RETRANS_PACKET *pRetrans = (NET_RETRANS_PACKET*)( pPacket->cPacketData + sizeof(NET_SVR_RS_CONTEXT) );

			UINT16 nCameraPos = pContext->nSvrRsCameraPos;
			if( 0 <= nCameraPos && nCameraPos < TG_SVRNET_MAXCHANNEL )
			{
				TG_AUTO_LOCK xLock(&m_xCameraSect[nCameraPos]);

				SvrNetRPCamera *pCamera = m_arCamera[nCameraPos];
				if( NULL != pCamera )
				{
					pCamera->SetCmdRetransPacket(pContext,pPacket);
				}
			}
		}
		break;
	default:
		{
			break;
		} 
	}

	m_pReadCmdNode->nWriteFlag = 1;
	m_pReadCmdNode = m_pReadCmdNode->pNext;
}
